import tkinter as tk
from tkinter import ttk, simpledialog, filedialog, messagebox
import csv
from datetime import datetime
from tkinterdnd2 import TkinterDnD, DND_TEXT

# 创建主窗口
root = TkinterDnD.Tk()
root.title("To-Do List with Kanban Board")

# 创建 Treeview 控件，并指定列名
tree = ttk.Treeview(root, columns=("Priority", "Content", "Begin Time", "End Time"), show="headings")
tree.heading("Priority", text="Priority")
tree.heading("Content", text="Content")
tree.heading("Begin Time", text="Begin Time")
tree.heading("End Time", text="End Time")

# 设置每列的宽度
tree.column("Priority", width=50)
tree.column("Content", width=200)
tree.column("Begin Time", width=100)
tree.column("End Time", width=100)

# 添加滚动条
vsb = ttk.Scrollbar(root, orient="vertical", command=tree.yview)
hsb = ttk.Scrollbar(root, orient="horizontal", command=tree.xview)
tree.configure(yscrollcommand=vsb.set, xscrollcommand=hsb.set)

# 将滚动条放置到窗口中
vsb.pack(side='right', fill='y')
hsb.pack(side='bottom', fill='x')

# 将 Treeview 放置到主窗口中
tree.pack(expand=True, fill=tk.BOTH)

# 加载数据
def load_data(file_path):
    with open(file_path, newline='') as file:
        reader = csv.reader(file)
        for row in reader:
            insert_and_color_row(row)

# 保存数据
def save_data():
    file_path = filedialog.asksaveasfilename(defaultextension=".csv")
    if not file_path:
        return
    with open(file_path, 'w', newline='') as file:
        writer = csv.writer(file)
        for child_id in tree.get_children():
            row = tree.item(child_id)['values']
            writer.writerow(row)
    messagebox.showinfo("Info", "Data saved successfully")

# 添加新数据
def add_new_data():
    user_input = simpledialog.askstring("Input", "Please enter some data (Priority, Content, Begin Time, End Time):")
    if user_input:
        try:
            priority, content, begin_time, end_time = user_input.split(',')
            insert_and_color_row([priority, content, begin_time, end_time])
        except ValueError:
            messagebox.showerror("Error", "Invalid input format. Please use: Priority, Content, Begin Time, End Time")

# 插入行并根据时间范围改变颜色
def insert_and_color_row(row):
    item_id = tree.insert('', 'end', values=row)
    priority, content, begin_time, end_time = row

    # 获取当前时间
    now = datetime.now()
    current_time = now.strftime("%H:%M")
    current = datetime.strptime(current_time, "%H:%M")
    Begin = datetime.strptime(begin_time, "%H:%M")
    End = datetime.strptime(end_time, "%H:%M")

    # 根据时间范围设置颜色
    if Begin > current:
        tree.tag_configure('future', background='lightgreen')
        tree.item(item_id, tags=('future',))
    elif End < current:
        tree.tag_configure('past', background='red')
        tree.item(item_id, tags=('past',))
    else:
        tree.tag_configure('current', background='yellow')
        tree.item(item_id, tags=('current',))

# 删除数据
def remove_data():
    selected_indices = tree.selection()
    if selected_indices:
        for index in reversed(selected_indices):
            tree.delete(index)

# 编辑任务
def edit_task():
    selected_item = tree.selection()
    if not selected_item:
        messagebox.showwarning("Warning", "Please select a task to edit.")
        return
    item = tree.item(selected_item[0])['values']
    new_data = simpledialog.askstring("Edit Task", f"Current data: {item}\nEnter new data (Priority, Content, Begin Time, End Time):")
    if new_data:
        try:
            new_priority, new_content, new_begin_time, new_end_time = new_data.split(',')
            tree.item(selected_item[0], values=(new_priority, new_content, new_begin_time, new_end_time))
        except ValueError:
            messagebox.showerror("Error", "Invalid input format. Please use: Priority, Content, Begin Time, End Time")

# 过滤任务
def filter_tasks():
    priority_filter = simpledialog.askstring("Filter Tasks", "Enter the priority to filter by (low, medium, high):")
    if priority_filter:
        for child_id in tree.get_children():
            row = tree.item(child_id)['values']
            if row[0] != priority_filter:
                tree.detach(child_id)

# 创建卡片
class DraggableCard(tk.Frame):
    def __init__(self, master, text, **kwargs):
        super().__init__(master, relief=tk.RAISED, borderwidth=1, **kwargs)
        self.label = tk.Label(self, text=text, anchor='w', padx=10, pady=5)
        self.label.pack(fill=tk.X)
        self.bind("<Button-1>", self.on_press)
        self.bind("<B1-Motion>", self.on_drag)
        self._drag_data = {"x": 0, "y": 0}

    def on_press(self, event):
        self._drag_data["x"] = event.x
        self._drag_data["y"] = event.y

    def on_drag(self, event):
        delta_x = event.x - self._drag_data["x"]
        delta_y = event.y - self._drag_data["y"]
        x = self.winfo_x() + delta_x
        y = self.winfo_y() + delta_y
        self.place(x=x, y=y)

    def drop(self, target_frame):
        self.place_forget()
        self.master = target_frame
        self.pack(pady=5, fill=tk.X)

# 创建看板
def create_kanban_board():
    kanban_window = tk.Toplevel(root)
    kanban_window.title("Kanban Board")

    # 创建三个框架
    to_do_frame = tk.Frame(kanban_window, relief=tk.SUNKEN, borderwidth=1)
    in_progress_frame = tk.Frame(kanban_window, relief=tk.SUNKEN, borderwidth=1)
    done_frame = tk.Frame(kanban_window, relief=tk.SUNKEN, borderwidth=1)

    # 填充初始数据到相应的框架
    frames = {
        "To_Do": to_do_frame,
        "In Progress": in_progress_frame,
        "Done": done_frame
    }

    for frame_name, frame in frames.items():
        label = tk.Label(frame, text=frame_name, bg='lightblue', font=('Arial', 12, 'bold'))
        label.pack(fill=tk.X)
        frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
        frame.drop_target_register(DND_TEXT)
        frame.dnd_bind('<<Drop>>', lambda e, f=frame: on_drop(e, f))
    def add_task_to_todo():
        task = simpledialog.askstring("Input", "Enter the new task:")
        if task:
            card = DraggableCard(to_do_frame, task)
            card.pack(pady=5, fill=tk.X)

    # 创建新任务按钮
    add_task_button = tk.Button(kanban_window, text="Add New Task", command=add_task_to_todo)
    add_task_button.pack(pady=10)
    # 获取当前时间
    now = datetime.now()
    current_time = now.strftime("%H:%M")
    current = datetime.strptime(current_time, "%H:%M")

    # 遍历Treeview中的所有项目
    for child_id in tree.get_children():
        row = tree.item(child_id)['values']
        priority, content, begin_time, end_time = row
        Begin = datetime.strptime(begin_time, "%H:%M")
        End = datetime.strptime(end_time, "%H:%M")

        if Begin > current:
            target_frame = to_do_frame
        elif Begin <= current < End:
            target_frame = in_progress_frame
        else:
            target_frame = done_frame

        # 创建卡片并添加到目标框架
        card_text = f"Task: {content}, Priority: {priority}, Begin: {begin_time}, End: {end_time}"
        card = DraggableCard(target_frame, card_text)
        card.pack(pady=5, fill=tk.X)

# 处理拖放事件
def on_drop(event, target_frame):
    source = event.widget
    while not isinstance(source, DraggableCard):
        source = source.master
    source.drop(target_frame)

# 创建按钮以创建看板
kanban_button = tk.Button(root, text="Create Kanban Board", command=create_kanban_board)
kanban_button.pack(pady=10)

# 加载按钮
load_button = tk.Button(root, text="Load Data", command=lambda: load_data(filedialog.askopenfilename()))
load_button.pack(side=tk.LEFT, padx=5, pady=5)

# 保存按钮
save_button = tk.Button(root, text="Save Data", command=save_data)
save_button.pack(side=tk.RIGHT, padx=5, pady=5)

# 添加按钮
add_button = tk.Button(root, text="Add New Data", command=add_new_data)
add_button.pack(pady=10)

# 删除按钮
remove_button = tk.Button(root, text="Remove Data", command=remove_data)
remove_button.pack()

# 编辑按钮
edit_button = tk.Button(root, text="Edit Task", command=edit_task)
edit_button.pack(pady=10)

# 过滤按钮
filter_button = tk.Button(root, text="Filter Tasks", command=filter_tasks)
filter_button.pack(pady=10)

# 运行主循环
root.mainloop()